package com.leslie.hhcommunity.controller.interceptor;


import com.leslie.hhcommunity.entity.LoginTicket;
import com.leslie.hhcommunity.entity.User;
import com.leslie.hhcommunity.service.UserService;
import com.leslie.hhcommunity.util.CookieUtil;
import com.leslie.hhcommunity.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;


@Component
public class LoginTicketInterceptor implements HandlerInterceptor {

	@Autowired
	UserService userService;
	@Autowired
	HostHolder hostHolder;

	//在Controller之前执行
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		//从cookie中获取凭证
		String ticket = CookieUtil.getValue(request, "ticket");

		if (ticket != null) {
			//查询凭证
			LoginTicket loginTicket = userService.findLoginTicket(ticket);
			//查询凭证是否有效
			if (loginTicket != null && loginTicket.getStatus() == 0 && loginTicket.getExpired().after(new Date())) {
				//根据凭证查询用户
				User user = userService.findUserById(loginTicket.getUserId());
				// 让本次请求中持有用户
				hostHolder.setUser(user);

				/*由于我们是自己实现登录认证的，因此SecurityContext中并没有存入用户认证之后的Token，
				这样spring security就无法对当前用户进行认证，因此我们还需要将认证信息加入到SecurityContext中。
				首先我们要在UserService中加入得到用户权限的方法，同样的也是将type转成GrantedAuthority实例加入到List中返回即可
				*/

				// 构建用户认证的结果,并存入SecurityContext,以便于Security进行授权.
				Authentication authentication = new UsernamePasswordAuthenticationToken(
						user, user.getPassword(), userService.getAuthorities(user.getId()));
				SecurityContextHolder.setContext(new SecurityContextImpl(authentication));
			}
		}
		return true;
	}

	//在Controller之后执行
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		User user = hostHolder.getUser();
		if (user != null && modelAndView != null){
			modelAndView.addObject("loginUser",user);
		}
	}

	//在模板引擎之后执行
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		hostHolder.clear();
		SecurityContextHolder.clearContext();
	}
}
